01 分式规划

我们需要求解这样的问题:给定长度为 的序列 (),求

或者说,给定 维列向量 (),求

其中 是一个行向量。这就是最基本的 01 分式规划问题。

问题转化

设分式等于 。即

。对于任意一个 ,都可以求出一条直线 。当 时,

也就是说,平面上有若干条斜率为负的直线,要求出直线与 轴交点的最大值(最右边的点)。

二分法

假设随便取一个 。对于所有的 ,若存在 ,那么这条 轴的交点一定在 的右边。否则,没有交点在 的右边,答案一定在 左边。

这是一个很经典的二分答案的形式,所以就二分答案做了。关键是,如何判断存在

其实就是判断 。就是,已知 ,要求 的最大值。这个就很简单了。将式子转化为 。显然贪心可以做,若 是正数我们就取,否则不取。

设答案精度为 (因为分式通常是小数答案),那么复杂度是

Dinkelbach

还是刚才的思路,仅略作改变。若 ,那么我们贪心地,顺着这条 找到它与 轴的交点,把这个交点作为新的 ,继续求解。这就是 Dinkelbach 算法。

Dinkelbach 解决 01 分数规划的复杂度是 ,并且有跑不满、常数小的优势。证明留坑待填。先放一个网上的证明:对于0-1分数规划的Dinkelbach算法的分析

带限制的规划

有时候不一定是可以随便选。下面将提及几种带限制问题。

带限制问题,总体思路也不变,只是如何判断 罢了。

选不超过

这个简单。就在选正数的基础上,只选前 大的就可以了。

选择不能相邻

做一个 dp 即可。设 表示第 个选或未选,贡献的最大值。那么

选择有树形依赖

比如 Desert King 那道题。求一个最大生成树即可。

也有可能是树形 dp。

选择不超过 个,且不能相邻

做一个反悔贪心板子。类似题目:CTSC2007 数据备份。

选择的 的和有上下界

也就是, 这种。可以用背包 dp。板题:[USACO18OPEN] Talent Show G

只能选择连续一段,并且选择的 的和有上下界

连续一段可以前缀和。也就是判断是否存在 。移项可得 ,再变成是否存在

注意到每个 对应的 也是连续的一段,并且单调,可以双指针维护段的左右端点。然后单调队列滑动窗口求解。


总之 01 分式规划不难。但是将一个问题转化成 01 分式规划可能需要一定的思维。

感觉越写越水了。就讲到这里吧。